package com.sunck.modules.system.utils;

import com.sunck.common.utils.RedisUtils;
import com.sunck.common.utils.bean.BeanUtils;
import com.sunck.modules.system.entity.Menu;
import com.sunck.modules.system.entity.Office;
import com.sunck.modules.system.entity.Role;
import com.sunck.modules.system.entity.User;
import com.sunck.modules.system.service.MenuService;
import com.sunck.modules.system.service.OfficeService;
import com.sunck.modules.system.service.RoleService;
import com.sunck.modules.system.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * 用户工具类
 *
 * @author LengChen
 * @version 1.0
 * @date 2020/8/17
 */
@Component
public class UserUtils {


    private static UserUtils userUtils;
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private MenuService menuService;
    @Autowired
    private OfficeService officeService;


    @PostConstruct
    public void init() {
        userUtils = this;
        userUtils.userService = this.userService;
        userUtils.roleService = this.roleService;
        userUtils.redisUtils = this.redisUtils;
        userUtils.menuService = this.menuService;
        userUtils.officeService = this.officeService;
    }

    /**
     * 用户缓存HashKey
     */
    public static  final  String USER_CACHE = "user_cache";
    /**
     * 用户ID
     */
    public static  final  String USER_CACHE_ID_ = "id_";
    /**
     * 用户登录名
     */
    public static  final  String USER_CACHE_LOGIN_NAME_ = "ln_";
    /**
     * 用户部门ID
     */
    public static  final  String USER_CACHE_LIST_BY_OFFICE_ID_ = "oid_";


    public static final String CACHE_ROLE_LIST = "roleList";
    public static final String CACHE_MENU_LIST = "menuList";
    public static final String CACHE_AREA_LIST = "areaList";
    public static final String CACHE_OFFICE_LIST = "officeList";
    public static final String CACHE_OFFICE_ALL_LIST = "officeAllList";


    /**
     * 根据登录名获取用户
     * @param loginCode
     * @return 取不到返回null
     */
    public static User getByLoginCode(String loginCode){
        User user = (User)userUtils.redisUtils.getHashValue(USER_CACHE, USER_CACHE_LOGIN_NAME_ + loginCode);;
        if (user == null){
            user = userUtils.userService.getUser(loginCode);
            if (user != null){
                refreshUserCache(user);
            }
        }
        return user;
    }

    /**
     * 根据ID获取用户
     * @param userCode
     * @return 取不到返回null
     */
    public static User getByUserCode(String userCode){
        User user = (User)userUtils.redisUtils.getHashValue(USER_CACHE, USER_CACHE_ID_ + userCode);
        if (user ==  null){
            user = userUtils.userService.get(userCode);
            if (user != null){
                refreshUserCache(user);
            }
        }
        return user;
    }

    /**
     * 刷新用户缓存
     */
    public static void refreshUserCache(User user){
        //user.setRoleList(userUtils.roleService.findList(new Role(user)));
        userUtils.redisUtils.setHash(USER_CACHE, USER_CACHE_ID_ + user.getUserCode(), user);
        userUtils.redisUtils.setHash(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginCode(), user);
    }

    /**
     * 清除指定用户缓存
     * @param user
     */
    public static void clearCache(User user){
        userUtils.redisUtils.removeHashKey(USER_CACHE, USER_CACHE_ID_ + user.getUserCode());
        userUtils.redisUtils.removeHashKey(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginCode());
        if (user.getOffice() != null && user.getOffice().getOfficeCode() != null){
            userUtils.redisUtils.removeHashKey(USER_CACHE, USER_CACHE_LIST_BY_OFFICE_ID_ + user.getOffice().getOfficeCode());
        }
    }


// ============== User SessionCache utils ==============

    public static Session getSession(){
        try {
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession(false);
            if (session == null){
                session = subject.getSession();
            }
            if (session != null){
                return session;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static Object getCache(String key) {
        return getCache(key, null);
    }

    public static Object getCache(String key, Object defaultValue) {
        Object obj = getSession().getAttribute(key);
        return obj==null?defaultValue:obj;
    }

    public static void putCache(String key, Object value) {
        getSession().setAttribute(key, value);
    }

    public static void removeCache(String key) {
        getSession().removeAttribute(key);
    }

    public static Object getRemoveCache(String key) {
       return getRemoveCache(key,null);
    }

    public static Object getRemoveCache(String key, Object defaultValue) {
        Object obj = getSession().getAttribute(key);
        getSession().removeAttribute(key);
        return obj==null?defaultValue:obj;
    }

    /**
     * 获取当前登录用户（session）
     * @return
     */
    public static User getUser() {
        User user = null;
        Object obj =  SecurityUtils.getSubject().getPrincipal();
        if (obj != null)
        {
            user = new User();
            BeanUtils.copyBeanProp(user, obj);
        }
        return user;
    }

    /**
     * 获取当前用户角色列表（session）
     * @return
     */
    public static List<Role> getRoleList(){
        @SuppressWarnings("unchecked")
        List<Role> roleList = (List<Role>)getCache(CACHE_ROLE_LIST);
        if (roleList == null){
            User user = getUser();
            if (user.isAdmin()){
                roleList = userUtils.roleService.findList(new Role());
            }else{
                Role role = new Role();
                /*role.getSqlMap().put("dsf", BaseService.dataScopeFilter(user.getCurrentUser(), "o", "u"));*/
                roleList =  userUtils.roleService.findList(role);
            }
            putCache(CACHE_ROLE_LIST, roleList);
        }
        return roleList;
    }

    /**
     * 获取当前用户授权菜单（session）
     * @return
     */
    public static List<Menu> getMenuList(){
        @SuppressWarnings("unchecked")
        List<Menu> menuList = (List<Menu>)getCache(CACHE_MENU_LIST);
        if (menuList == null){
            User user = getUser();
            if (user.isAdmin()){
                menuList = userUtils.menuService.findList(new Menu());
            }else{
                Menu menu = new Menu();
                menu.setUser(user.getUserCode());
                menuList = userUtils.menuService.findByUserId(menu);
            }
            putCache(CACHE_MENU_LIST, menuList);
        }
        return menuList;
    }

    /**
     * 获取当前用户有权限访问的部门（session）
     * @return
     */
    public static List<Office> getOfficeList(){
        @SuppressWarnings("unchecked")
        List<Office> officeList = (List<Office>)getCache(CACHE_OFFICE_LIST);
        if (officeList == null){
            User user = getUser();
            if (user.isAdmin()){
                officeList = userUtils.officeService.findList(new Office());
            }else{
                Office office = new Office();
                /*office.getSqlMap().put("dsf", BaseService.dataScopeFilter(user, "a", ""));*/
                officeList = userUtils.officeService.findList(office);
            }
            putCache(CACHE_OFFICE_LIST, officeList);
        }
        return officeList;
    }

    /**
     * 获取当前用户有权限访问的部门（session）
     * @return
     */
    public static List<Office> getOfficeAllList(){
        @SuppressWarnings("unchecked")
        List<Office> officeList = (List<Office>)getCache(CACHE_OFFICE_ALL_LIST);
        if (officeList == null){
            officeList = userUtils.officeService.findList(new Office());
        }
        return officeList;
    }

    /**
     * 清除当前用户缓存（session）
     */
    public static void clearCache(){
        removeCache(CACHE_ROLE_LIST);
        removeCache(CACHE_MENU_LIST);
        removeCache(CACHE_AREA_LIST);
        removeCache(CACHE_OFFICE_LIST);
        removeCache(CACHE_OFFICE_ALL_LIST);
        UserUtils.clearCache(getUser());
    }
}
